﻿using AutoMapper.Internal.Mappers;
using Business.BookManagement.Dto;
using Business.BookManagement;
using Business.Permissions;
using Microsoft.AspNetCore.Authorization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Repositories;
using XCZ;
using Business.Models;
using Business.SaleManagement.Dto;
using Microsoft.EntityFrameworkCore;
using Yitter.IdGenerator;
using System.Xml.Linq;
using System.Diagnostics.Contracts;
using System.Net;
using WkHtmlToPdfDotNet;
using Business.AssembleInfoManagement.Dto;
using Volo.Abp.ObjectMapping;
using Business.SaProManagement.Dto;

namespace Business.SaleManagement
{
    //[Authorize(BusinessPermissions.Sale.Default)]
    public class SaleAppService : BusinessWorkFlowAppService, ISaleAppService
    {
        private const string FormName = "Sale";
        private IRepository<Sale, Guid> _repository;
        private IRepository<SaPro, Guid> _repository1;

        public SaleAppService(IRepository<Sale, Guid> repository, IRepository<SaPro, Guid> repository1)
        {
            _repository = repository;
            _repository1 = repository1;
        }
        #region 增删改查基础方法

        public async Task<SaleDto> Get(Guid id)
        {
            var data = await _repository.GetAsync(id);
            var dto = ObjectMapper.Map<Sale, SaleDto>(data);
            return dto;
        }

        public async Task<PagedResultDto<SaleDto>> GetAll(GetSaleInputDto input)
        {
            var query = await _repository.GetQueryableAsync();

            var totalCount = await query.CountAsync();
            var items = await query.OrderBy(input.Sorting ?? "Id")
                        .ToListAsync();

            var dtos = ObjectMapper.Map<List<Sale>, List<SaleDto>>(items);
            return new PagedResultDto<SaleDto>(totalCount, dtos);
        }

        public async Task<PagedResultDto<SaleAllInfo>> GetAllinfo(GetSaleInputDto input)
        {
            var query = (from a in await _repository.GetQueryableAsync()
                         join b in await _repository1.GetQueryableAsync() on a.Id.ToString() equals b.Spid
                         select new SaleAllInfo
                         {
                             Id = a.Id,
                             Suname = a.Suname,
                             Sucontract = a.Sucontract,
                             Supersonnel = a.Supersonnel,
                             Returnpersonnel = a.Returnpersonnel,
                             Dosubject=a.Dosubject,
                             Recode=a.Recode,
                             Representative=a.Representative,
                             MyRepresentative=a.MyRepresentative,
                             Retype=a.Retype,
                             Redatetimes=a.Redatetimes,
                             Reitem=a.Reitem,
                             Refundway=a.Refundway,
                             Reway=a.Reway,
                             Readdress=a.Readdress,
                             Redesc=a.Redesc,
                             Spid=b.Spid,
                             Saname=b.Saname,
                             Sacode=b.Sacode,
                             Saspecification=b.Saspecification,
                             Saunit=b.Saunit,
                             Sanum=b.Sanum,
                             Saprice=b.Saprice,
                             Sabilltype=b.Sabilltype,
                             Sarate=b.Sarate,
                             SainclusivePrice=b.SainclusivePrice,
                             Sauntaxedmoney=b.Sauntaxedmoney,
                             Saamount=b.Saamount,
                             Sasummoney=b.Sasummoney,
                             Saselect=b.Saselect,
                             Lotnumber=b.Lotnumber,
                             Effectivedate=b.Effectivedate,
                             Givedate=b.Givedate,
                             Arrivedate=b.Arrivedate,
                             Sadesc=b.Sadesc,
                         }).ToList();
            var totalCount = query.Count();
            query = query.Skip(input.SkipCount).Take(input.MaxResultCount).ToList();
            return new PagedResultDto<SaleAllInfo>(totalCount, query);
        }

        public async Task<SaleDto> CreateOrUpdate(CreateOrUpdateSaleDto input)
        {
            Sale result = null;
            Random random = new Random();
            if (!input.Id.HasValue)
            {
                input.Id = GuidGenerator.Create();
                input.Recode = "JH" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + random.Next(1000,10000);
                Sale sale = new Sale()
                {
                    Suname = input.Suname,
                    Sucontract = input.Sucontract,
                    Supersonnel = input.Supersonnel,
                    Returnpersonnel = input.Returnpersonnel,
                    Dosubject = input.Dosubject,
                    Recode = input.Recode,
                    Representative = input.Representative,
                    MyRepresentative = input.MyRepresentative,
                    Retype = input.Retype,
                    Redatetimes = DateTime.Now,
                    Reitem = input.Reitem,
                    Refundway = input.Refundway,
                    Reway = input.Refundway,
                    Readdress = input.Readdress,
                    Redesc = input.Redesc,
                };

                foreach (var item in input.ProduceSapro)
                {
                    SaPro sp = new SaPro()
                    {
                        Spid = Convert.ToString(input.Id),
                        Saname = item.Saname,
                        Sacode = item.Sacode,
                        Saspecification = item.Saspecification,
                        Saunit = item.Saunit,
                        Sanum = item.Sanum,
                        Saprice = item.Saprice,
                        Sabilltype = item.Sabilltype,
                        Sarate = item.Sarate,
                        SainclusivePrice = item.SainclusivePrice,
                        Sauntaxedmoney = item.Sauntaxedmoney,
                        Saamount = item.Saamount,
                        Sasummoney = item.Sasummoney,
                        Saselect = item.Saselect,
                        Lotnumber = item.Lotnumber,
                        Effectivedate = DateTime.Now,
                        Givedate = DateTime.Now,
                        Arrivedate = DateTime.Now,
                        Sadesc = item.Sadesc,
                    };
                    await _repository1.InsertManyAsync(new List<SaPro>() { sp });
                }
                result = await _repository.InsertAsync(ObjectMapper.Map<CreateOrUpdateSaleDto, Sale>(input));
            }
            else
            {
                var data = await _repository.GetAsync(input.Id.Value);
                Sale sale = new Sale()
                {
                    Suname = input.Suname,
                    Sucontract = input.Sucontract,
                    Supersonnel = input.Supersonnel,
                    Returnpersonnel = input.Returnpersonnel,
                    Dosubject = input.Dosubject,
                    Recode = input.Recode,
                    Representative = input.Representative,
                    MyRepresentative = input.MyRepresentative,
                    Retype = input.Retype,
                    Redatetimes = DateTime.Now,
                    Reitem = input.Reitem,
                    Refundway = input.Refundway,
                    Reway = input.Refundway,
                    Readdress = input.Readdress,
                    Redesc = input.Redesc,
                };

                foreach (var item in input.ProduceSapro)
                {
                    SaPro sp = new SaPro()
                    {
                        Spid = Convert.ToString(input.Id) ,
                        Saname = item.Saname,
                        Sacode = item.Sacode,
                        Saspecification = item.Saspecification,
                        Saunit = item.Saunit,
                        Sanum = item.Sanum,
                        Saprice = item.Saprice,
                        Sabilltype = item.Sabilltype,
                        Sarate = item.Sarate,
                        SainclusivePrice = item.SainclusivePrice,
                        Sauntaxedmoney = item.Sauntaxedmoney,
                        Saamount = item.Saamount,
                        Sasummoney = item.Sasummoney,
                        Saselect = item.Saselect,
                        Lotnumber = item.Lotnumber,
                        Effectivedate = DateTime.Now,
                        Givedate = DateTime.Now,
                        Arrivedate = DateTime.Now,
                        Sadesc = item.Sadesc,
                    };
                    await _repository1.InsertManyAsync(new List<SaPro>() { sp });
                }
                result = await _repository.UpdateAsync(ObjectMapper.Map(input, data));
            }
            return ObjectMapper.Map<Sale, SaleDto>(result);
        }

        public async Task<CreateOrUpdateSaleDto> GetSaleAll(string id)
        {
            var prodeces=await _repository1.GetQueryableAsync();
            var list = (from a in await _repository.GetQueryableAsync()
                        where a.Id.ToString() == id
                        select new CreateOrUpdateSaleDto
                        {
                            Suname = a.Suname,
                            Sucontract = a.Sucontract,
                            Supersonnel = a.Supersonnel,
                            Returnpersonnel = a.Returnpersonnel,
                            Dosubject = a.Dosubject,
                            Recode = a.Recode,
                            Representative = a.Representative,
                            MyRepresentative = a.MyRepresentative,
                            Retype = a.Retype,
                            Redatetimes = a.Redatetimes,
                            Reitem = a.Reitem,
                            Refundway = a.Refundway,
                            Reway = a.Reway,
                            Readdress = a.Readdress,
                            Redesc = a.Redesc,
                            ProduceSapro = (from b in prodeces
                                            where a.Id.ToString() == b.Spid
                                            select new SaProDto()
                                            {
                                                Spid=b.Spid,
                                                Saname=b.Saname,
                                                Sacode=b.Sacode,
                                                Saspecification=b.Saspecification,
                                                Saunit=b.Saunit,
                                                Sanum=b.Sanum,
                                                Saprice=b.Saprice,
                                                Sabilltype=b.Sabilltype,
                                                Sarate=b.Sarate,
                                                SainclusivePrice=b.SainclusivePrice,
                                                Sauntaxedmoney=b.Sauntaxedmoney,
                                                Saamount=b.Saamount,
                                                Sasummoney=b.Sasummoney,
                                                Saselect=b.Saselect,
                                                Lotnumber=b.Lotnumber,
                                                Effectivedate=b.Effectivedate,
                                                Givedate=b.Givedate,
                                                Arrivedate=b.Arrivedate,
                                                Sadesc=b.Sadesc,
                                            }).ToList()
                        }).FirstOrDefault();
            return list;
        }

        public async Task Delete(List<Guid> ids)
        {
            foreach (var item in ids)
            {
                await _repository.DeleteAsync(item);
            }

        }
        #endregion

    }
}
